package xpn.platform.modules.login;

import java.util.List;
import java.util.Set;

import javax.script.ScriptException;
import javax.servlet.http.HttpServletRequest;

import com.google.common.base.Strings;

import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
//import xpn.business.sandbox.loginrecord.LoginRecordService;
import xpn.platform.common.config.XpnPlatformConfig;
import xpn.platform.common.exception.XpnAuthenticationException;
import xpn.platform.common.exception.XpnBusinessException;
import xpn.platform.common.exception.XpnExceptionCodeEnum;
import xpn.platform.common.util.Tool;
import xpn.platform.modules.sys.permission.SysPermissionService;
import xpn.platform.modules.sys.user.SysUser;

/**
 * 登录服务实现
 *
 * @author duwei
 */
@Service
public class LoginServiceImpl implements LoginService {

	@Autowired
	XpnPlatformConfig xpnPlatformConfig;

	@Autowired
	private SysPermissionService sysPermissionService;

//	@Autowired
//	private LoginRecordService loginRecordService;


	@Override
	public LoginOkDTO login(String paramUserName, String paramPassword, HttpServletRequest request) {

		String userName = LoginUtil.getUserName(paramUserName, request);
		String password = LoginUtil.getPassword(paramPassword, request);

		// 1 根据传人的用户名和密码创建验证token
		String pass;
		String passwordDigest = xpnPlatformConfig.getSecurity().getPasswordDigest();
		if (!Strings.isNullOrEmpty(passwordDigest) && !"none".equals(passwordDigest.toLowerCase())) {
			pass = Tool.MD5(password);
		} else {
			pass = password;
		}
		UsernamePasswordToken authToken = new UsernamePasswordToken(userName, pass);
		// 2 用验证token登录
		// 首先触发ShiroAuthorizingRealm的登录方法，登录成功后触发ShiroAuthorizingRealm的授权方法
		Subject subject = SecurityUtils.getSubject();
		try {
			subject.login(authToken);
		} catch (AuthenticationException e) {
			throw new XpnBusinessException(XpnExceptionCodeEnum.LOGIN_FALED);
		}

		// 3 登录成功，构造并返回登录成功Dto
		String tokenStr = (String) subject.getSession().getId();

		LoginOkDTO.Token loginToken = new LoginOkDTO.Token(xpnPlatformConfig.getSecurity().getAuthenticationTokenName(),
				tokenStr);

		// 3.2 获得用户的权限列表
		SysUser user = (SysUser) subject.getPrincipals().getPrimaryPrincipal();
		if (user.getLocked()) { // 用户帐号被锁定
			throw new XpnBusinessException(XpnExceptionCodeEnum.USER_ACCOUNT_LOCKED);
		}

		Set<String> permissions;
		try {
			permissions = sysPermissionService.getUserPermissions(user);
		} catch (ScriptException e) {
			e.printStackTrace();
			throw new XpnBusinessException(XpnExceptionCodeEnum.RULE_SCRIPT_FAILED, e.getMessage());
		}

		LoginOkDTO loginOkDTO = new LoginOkDTO(user, loginToken, permissions);
		// 将登录成功Dto传给LoginRecordService构造登录信息对象并存入数据库
		//loginRecordService.addOneLoginRecord(loginOkDTO);

		return loginOkDTO;
	}

	@Override
	public void logout() {
		Subject subject = SecurityUtils.getSubject();
		subject.logout();
	}

	@Override
	public Object authFrom4A(String paramUserName, String paramPassword, HttpServletRequest request) {
        JSONObject ret=new JSONObject();
		String userName = LoginUtil.getUserName(paramUserName, request);
		String password = LoginUtil.getPassword(paramPassword, request);
        String errorMsg="";
        String tokenStr="";
		// 1 根据传人的用户名和密码创建验证token
		String pass;
		String passwordDigest = xpnPlatformConfig.getSecurity().getPasswordDigest();
		if (!Strings.isNullOrEmpty(passwordDigest) && !"none".equals(passwordDigest.toLowerCase())) {
			pass = Tool.MD5(password);
		} else {
			pass = password;
		}
		UsernamePasswordToken authToken = new UsernamePasswordToken(userName, pass);
		// 2 用验证token登录
		// 首先触发ShiroAuthorizingRealm的登录方法，登录成功后触发ShiroAuthorizingRealm的授权方法
		Subject subject = SecurityUtils.getSubject();
		try {
			subject.login(authToken);
			// 3 登录成功，构造并返回登录成功Dto
			tokenStr = (String) subject.getSession().getId();

			LoginOkDTO.Token loginToken = new LoginOkDTO.Token(xpnPlatformConfig.getSecurity().getAuthenticationTokenName(),
					tokenStr);
			// 3.2 获得用户的权限列表
			SysUser user = (SysUser) subject.getPrincipals().getPrimaryPrincipal();
			if (user.getLocked()) { // 用户帐号被锁定
				errorMsg="用户被锁定!";
			}

		} catch (AuthenticationException e) {
			Throwable throwE=e.getCause();
			if(throwE instanceof XpnBusinessException){
				XpnBusinessException xe=(XpnBusinessException)throwE;
                if(xe.getErrorCode().equals(2)){
					errorMsg="用户不存在!";
				}
				else if(xe.getErrorCode().equals(3)){
					errorMsg="用户被锁定!";
				}
				else{
					errorMsg="用户验证失败!";
				}
			}else{
				errorMsg="用户验证失败!";
			}
		}
		if(!errorMsg.equals("")){
			ret.put("errorMsg",errorMsg);
		}else{
			ret.put("xpnToken",tokenStr);
		}
		return ret;
	}


	@Override
	public Object login(String token, HttpServletRequest request) throws XpnAuthenticationException {

		try {
			Subject subject = SecurityUtils.getSubject();
			String tokenStr = (String) subject.getSession().getId();
			LoginOkDTO.Token loginToken = new LoginOkDTO.Token(
					xpnPlatformConfig.getSecurity().getAuthenticationTokenName(), tokenStr);

			// 3.2 获得用户的权限列表
			SysUser user = (SysUser) subject.getPrincipals().getPrimaryPrincipal();
			if (user.getLocked()) { // 用户帐号被锁定
				throw new XpnBusinessException(XpnExceptionCodeEnum.USER_ACCOUNT_LOCKED);
			}

			Set<String> permissions;
			try {
				permissions = sysPermissionService.getUserPermissions(user);
			} catch (ScriptException e) {
				e.printStackTrace();
				throw new XpnBusinessException(XpnExceptionCodeEnum.RULE_SCRIPT_FAILED, e.getMessage());
			}

			return new LoginOkDTO(user, loginToken, permissions);
		} catch (AuthenticationException e) {
			throw new XpnBusinessException(XpnExceptionCodeEnum.LOGIN_FALED);
		}
	}
}
